﻿using System;
using System.Data;
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using Doan.Website.Models;
using Ext.Net;
using Ext.Net.MVC;
using System.Linq.Dynamic;
using log4net;

namespace Doan.Website.Controllers
{
    [DirectController]
    public class AccountController : Controller
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(AccountController).Name);
        private static DoAnWebsiteEntities db = new DoAnWebsiteEntities();
        public IFormsAuthenticationService FormsService { get; set; }
        public IMembershipService MembershipService { get; set; }

        protected override void Initialize(RequestContext requestContext)
        {
            if (FormsService == null) { FormsService = new FormsAuthenticationService(); }
            if (MembershipService == null) { MembershipService = new AccountMembershipService(); }
            base.Initialize(requestContext);
        }


        // **************************************
        // URL: /Account/ForgotPassword
        // **************************************

        public ActionResult AcessDenied()
        {
            return View();
        }
        
        public ActionResult ForgotPassword()
        {
            return View();
        }

        [HttpPost]
        public ActionResult ForgotPassword(ForgotPassword model)
        {
            if (ModelState.IsValid)
            {
                MembershipUser user = Membership.GetUser(model.UserName);
                try
                {
                    if (user.Email != model.Email)
                    {
                        ViewBag.FogotPass = "Email không hợp lệ";
                    }
                    else
                    {
                        var temp = db.aspnet_Users.Single(m => m.UserName == model.UserName);
                        string resetPass = temp.UserId.ToString().Substring(0, 8);
                        user.ChangePassword(user.ResetPassword(), resetPass);
                        var user1 = db.aspnet_Membership.Single(m => m.UserId == temp.UserId);
                        user1.Comment = "need change pass";
                        db.SaveChanges();
                        string body = "Chào bạn " + model.UserName + "!" + "\n Mật khẩu mới của bạn là : " + resetPass +"\n Để đảm bảo tính bảo mật, bạn cần đổi mật khẩu ở lần đăng nhập đầu tiên";
                        try
                        {
                            ForgotPassService.SendMail(model.Email, body);
                            ViewBag.FogotPasssuccess = "Cấp lại mật khẩu thành công, hãy check mail để lấy lại mật khẩu";
                            return View();
                        }
                        catch (Exception ex)
                        {
                            log.Error("Can't send email: " + ex.Message);
                            ViewBag.FogotPass = "Không thể gửi được emai do Tên đăng nhập hoặc email không chính xác";
                        }
                    }
                }
                catch (Exception)
                {
                    ViewBag.FogotPass = "Tên đăng nhập không chính xác";
                }
            }

            // If we got this far, something failed, redisplay form
            return View();
        }

        // **************************************
        // URL: /Account/LogOff
        // **************************************

        public ActionResult LogOff()
        {
            FormsService.SignOut();
            return RedirectToAction("LogOn", "Account");
        }

        // **************************************
        // URL: /Account/LogOn
        // **************************************

        public ActionResult LogOn()
        {
            return View();
        }

        [HttpPost]
        public ActionResult LogOn(LogOnModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                if (MembershipService.ValidateUser(model.UserName, model.Password))
                {
                    FormsService.SignIn(model.UserName, model.RememberMe);
                    var temp = db.aspnet_Users.Single(m => m.UserName == model.UserName);
                    var user = db.aspnet_Membership.Single(m => m.UserId == temp.UserId);
                    const string comment = "need change pass";
                    if (user.Comment != null)
                    {
                        string test = user.Comment.ToString();
                        if(comment.Equals(test))
                        {
                            return RedirectToAction("ChangePasswordSite");
                        }
                    }
                    else if (Url.IsLocalUrl(returnUrl))
                    {
                        return Redirect(returnUrl);
                    }
                    return RedirectToAction("Index", "Admin");
                }
                else
                {
                    ViewBag.LogOn = "Tên đăng nhập hoặc mật khẩu không chính xác";
                }
            }
            return View();
        }

        // **************************************
        // URL: /Account/Register
        // **************************************

        [AccessDeniedAuthorize(Roles = "administrators")]
        public ActionResult Register()
        {
            ViewBag.PasswordLength = MembershipService.MinPasswordLength;
            ViewBag.Roles= db.aspnet_Roles.ToList().Select(ent => new ListItem { Text = ent.RoleName, Value = ent.RoleId.ToString()});
            return View();
        }

        [AccessDeniedAuthorize(Roles = "administrators")]
        [HttpPost]
        public ActionResult Register(RegisterModel model)
        {
            if (ModelState.IsValid)
            {
                // Attempt to register the user
                MembershipCreateStatus createStatus = MembershipService.CreateUser(model.UserName, model.Password, model.Email);

                if (createStatus == MembershipCreateStatus.Success)
                {
                    var cbb = X.GetCmp<ComboBox>("CBBRole");
                    if(cbb.SelectedItem!=null)
                    {
                        Roles.AddUserToRoles(model.UserName, new[] {cbb.SelectedItem.Text});
                    }
                    // return to list user
                    return RedirectToAction("RegisterSuccess");
                }
                else
                {
                    string error = AccountValidation.ErrorCodeToString(createStatus);
                    X.Msg.Alert("ERROR", error).Show();
                    log.Error("ERROR: "+error);
                }
            }

            // If we got this far, something failed, redisplay form
            ViewBag.Roles = db.aspnet_Roles.ToList().Select(ent => new ListItem { Text = ent.RoleName, Value = ent.RoleId.ToString() });
            ViewBag.PasswordLength = MembershipService.MinPasswordLength;
            return View(model);
        }

        public ActionResult RegisterSuccess()
        {
            return View();
        }

        // **************************************
        // URL: /Account/ChangePassword
        // **************************************

        [AccessDeniedAuthorize(Roles = "administrators, users")]
        public ActionResult ChangePassword()
        {
            ViewBag.PasswordLength = MembershipService.MinPasswordLength;
            return View();
        }

        [HttpPost]
        public ActionResult ChangePassword(ChangePasswordModel model)
        {
            if (ModelState.IsValid)
            {
                
                if (MembershipService.ChangePassword(User.Identity.Name, model.OldPassword, model.NewPassword))
                {
                    return RedirectToAction("ChangePasswordStatus");
                }
                else
                {
                    ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
                    X.Msg.Alert("Error!", "The Old password provided is incorrect").Show();
                }
            }

            // If we got this far, something failed, redisplay form
            ViewBag.PasswordLength = MembershipService.MinPasswordLength;
            return this.FormPanel();
        }

        public ActionResult ChangePasswordStatus()
        {
            var temp = db.aspnet_Users.Single(m => m.UserName == User.Identity.Name);
            var user1 = db.aspnet_Membership.Single(m => m.UserId == temp.UserId);
            user1.Comment = null;
            db.SaveChanges();
            return RedirectToAction("ChangePasswordSuccess");
        }

        public ActionResult ChangePasswordSuccess()
        {
            return View();
        }

        // **************************************
        // URL: /Account/ChangePasswordsite
        // **************************************

        [AccessDeniedAuthorize(Roles = "administrators, users")]
        public ActionResult ChangePasswordSite()
        {
            ViewBag.PasswordLength = MembershipService.MinPasswordLength;
            return View();
        }

        [HttpPost]
        public ActionResult ChangePasswordSite(ChangePasswordModel model)
        {
            if (ModelState.IsValid)
            {

                if (MembershipService.ChangePassword(User.Identity.Name, model.OldPassword, model.NewPassword))
                {
                    var temp = db.aspnet_Users.Single(m => m.UserName == User.Identity.Name);
                    var user1 = db.aspnet_Membership.Single(m => m.UserId == temp.UserId);
                    user1.Comment = null;
                    db.SaveChanges();
                    ViewBag.ChangePassSuccess="Đổi mật khẩu thành công, bạn có thể tiếp tục công việc";
                }
                else
                {
                    ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
                    ViewBag.ChangePass="Mật khẩu cung cấp chưa chính xác";
                }
            }
            return View();
        }

        // **************************************
        // URL: /Account/ListAcount
        // **************************************

        [AccessDeniedAuthorize(Roles = "administrators")]
        public ActionResult ListAcount()
        {
            Session["includeInActiveAccount"] = false;
            Session["CharFilterAccount"] = "";

            return View();
        }

        public ActionResult IncludeInActive()
        {
            var store = X.GetCmp<Store>("AccountStore");

            Session["includeInActiveAccount"] = !(bool)Session["includeInActiveAccount"];

            store.Reload();
            return this.Direct();
        }

        [DirectMethod]
        public ActionResult InActiveAccount(string a)
        {
            string test = "\"";
            var store = X.GetCmp<Store>("AccountStore");
            for (int i = 2; i < (a.Length-1); i++)
            {
                if (','.Equals(a[i])) i += 2;
                string temp = null;
                while (!(','.Equals(a[i])) && !(']'.Equals(a[i])) && !(test.Equals(a[i].ToString())))
                {
                    temp = temp + a[i];
                    i++;
                }
                aspnet_Users user = db.aspnet_Users.Single(c => c.UserName.Equals(temp));
                aspnet_Membership member = db.aspnet_Membership.Single(c => c.UserId == user.UserId);
                db.aspnet_Membership.Detach(member);
                member.IsApproved = !member.IsApproved;
                db.aspnet_Membership.Attach(member);
                db.ObjectStateManager.ChangeObjectState(member, EntityState.Modified);
                db.SaveChanges();
            }
            X.Msg.Alert("Sucess", "Edit Acount success!").Show();
            store.Reload();
            return this.FormPanel();
        }

        [DirectMethod]
        public ActionResult CharFilterAccount(string filterstring)
        {
            var store = X.GetCmp<Store>("AccountStore");
            Session["CharFilterAccount"] = filterstring;
            store.Reload();
            return this.Direct();
        }

        public ActionResult BindingStore(StoreRequestParameters parameters)
        {
            var sampleData = (from tab1 in db.aspnet_Membership
                              join tab2 in db.aspnet_Users on tab1.UserId equals tab2.UserId
                              select new
                              {
                                  tab1.UserId,
                                  tab2.UserName,
                                  tab1.Email,
                                  tab1.IsApproved
                              }

            );


            bool includeInActive = (bool)Session["includeInActiveAccount"];
            string charFilter = (string)Session["CharFilterAccount"];

            var result = sampleData.Where(ent => ((includeInActive || ent.IsApproved)));
            if ("0".Equals(charFilter))
            {
                result = sampleData.Where(ent => ((includeInActive || ent.IsApproved) &&
                    (ent.UserName.StartsWith("0") || ent.UserName.StartsWith("1") ||
                    ent.UserName.StartsWith("2") || ent.UserName.StartsWith("3") ||
                    ent.UserName.StartsWith("4") || ent.UserName.StartsWith("5") ||
                    ent.UserName.StartsWith("6") || ent.UserName.StartsWith("7") ||
                    ent.UserName.StartsWith("8") || ent.UserName.StartsWith("9")
                    )));
            }

            else
            {
                result = sampleData.Where(ent => ((includeInActive || (bool)ent.IsApproved) && ent.UserName.StartsWith(charFilter)));

            }

            // Sorting
            if (!string.IsNullOrEmpty(parameters.SimpleSort))
            {
                result = result.OrderBy(parameters.SimpleSort + (parameters.SimpleSortDirection == SortDirection.DESC ? " desc" : " asc"));
            }
            else
            {
                result = result.OrderBy(ent => ent.UserId);
            }

            // Paging
            int limit = parameters.Limit;
            if ((parameters.Start + parameters.Limit) > result.Count())
            {
                limit = result.Count() - parameters.Start;
            }

            var rangeData = (parameters.Start < 0 || limit < 0) ? result : result.Skip(parameters.Start).Take(limit);
            return this.Store(rangeData.Select(ent => new { ent.UserId, ent.UserName, ent.Email, ent.IsApproved }), result.Count());
        }
    }

}
